﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SqlSugar;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using NetTaste;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Logging;
using System.Linq.Expressions;
using NPOI.SS.Formula.Functions;
using DFGK_WMS.Model.Enum;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using static NPOI.HSSF.Util.HSSFColor;
using Microsoft.VisualBasic;

namespace DFGK_WMS.Repository
{
    /// <summary>
    /// 出库管理
    /// </summary>
    public class TShippingOrderDetailRepository : BaseRepository<TShippingOrderDetail>, ITShippingOrderDetailRepository
    {
        private readonly IMapper mapper;
        private readonly ITShippingLockCellRepository lockCellRepository;

        public TShippingOrderDetailRepository(DFGK_DB context, IMapper mapper,ITShippingLockCellRepository lockCellRepository) : base(context, mapper)
        {
            this.mapper = mapper;
            this.lockCellRepository = lockCellRepository;
        }

        /// <summary>
        /// 添加出库管理
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddTShippingOrderDetail(TShippingOrderDetail model)
        {
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    //订单号
                    //单据类型
                    //合同号
                    //物料分类 优先级为顶级 默认为0
                    //物料名称
                    var material = Context.TMaterials.Find(model.MaterialId);
                    if (material != null)
                    {
                        model.MaterialCode = material.Code;
                        model.MaterialName = material.Name;
                        model.MaterialTypeCode = material.TypeCode;
                        model.UnitId = material.UnitId;
                        model.UnitName = material.UnitName;
                    }

                    //物料批次信息
                    // 根据 MaterialId 和 MaterialName 查询对应的物料批次记录
                    var materialkey = Context.TMaterialKeys.FirstOrDefault(m =>
                        m.MaterialId == model.MaterialId && m.MaterialName == model.MaterialName);
                    if (materialkey != null)
                    {
                        model.BatchNo = materialkey.BatchNo;
                    }

                    //库房信息
                    var house = Context.TWarehouses.Find(model.WarehouseId);
                    if (house != null)
                    {
                        model.WarehouseCode = house.Code;
                        model.WarehouseName = house.Name;

                        // 根据 AreaName 和 WarehouseId 查询对应的库区记录
                        var area = Context.TAreas.FirstOrDefault(m =>
                            m.Name == model.AreaName && m.WhId == model.WarehouseId);
                        if (area != null)
                        {
                            model.AreaCode = area.Code;
                        }
                    }

                    //出库站台
                    var station = Context.TStations.Find(model.StationId);
                    if (station != null)
                    {
                        model.StationName = station.Name;
                    }

                    //出库数默认为0
                    model.PickedQty = model.Qty;
                    model.ShippedQty = 0;
                    model.Status = 0;
                    //部门
                    var userobj = Context.TUsers.Find(model.NowUserId);
                    if (userobj != null)
                    {
                        var deptobj = Context.TDepartments.Find(userobj.DepartmentId);
                        if (deptobj != null)
                        {
                            model.DeptName = deptobj.DepartmentName;
                            model.DeptCode = deptobj.DepartmentCode;
                        }
                    }

                    #region 审计字段

                    model.CreateUserId = model.NowUserId;
                    model.CreateUserName = model.NowUserRealName;
                    model.CreateDate = DateTime.Now;
                    model.ModifyUserId = model.NowUserId;
                    model.ModifyUserName = model.NowUserRealName;
                    model.ModifyDate = DateTime.Now;
                    model.AuditUserId = model.NowUserId;
                    model.AuditUserName = model.NowUserRealName;
                    model.AuditDate = DateTime.Now;
                    model.SubmitUserId = model.NowUserId;
                    model.SubmitUserName = model.NowUserRealName;
                    model.SubmitDate = DateTime.Now;

                    #endregion 审计字段

                    //供应商
                    var supper = Context.TSuppliers.Find(model.SupplierId);
                    if (supper != null)
                    {
                        model.SupplierName = supper.Name;
                    }

                    //货主
                    var owner = Context.TOwners.Find(model.OwnerId);
                    if (owner != null)
                    {
                        model.OwnerName = owner.Name;
                    }

                    Context.TShippingOrderDetails.Add(model);
                    Context.SaveChanges();

                    

                    //货位锁定明细
                    foreach (var item in model.LockCell)
                    {
                        var inv = Context.TInventories.Where(s => s.Id == item.InventoryId).FirstOrDefault();
                        inv.Status = 4;
                        //item.AvailableQty = item.AvailableQty - item.OutQty;
                        Context.TInventories.Update(inv);
                        //货位锁定明细
                        TShippingLockCell m = new TShippingLockCell();
                        m.OrderDetailId = model.Id;
                        m.InventoryId = item.InventoryId;
                        m.CellId = item.CellId;
                        m.CellCode = item.CellCode;
                        m.CellName = item.CellName;
                        m.PalletBarcode = item.PalletBarcode;
                        m.WhId = model.WarehouseId;
                        m.CellDepthIndex = 0;
                        //组垛Id不知道
                        m.StackingStorageId = 0;
                        m.OutQty = item.OutQty;
                        m.InventoryQty = item.InventoryQty;
                        m.MaterialId = item.MaterialId;
                        m.MaterialName = item.MaterialName;
                        m.MaterialCode = item.MaterialCode;
                        m.MaterialKeyId = item.MaterialKeyId;
                        m.BatchNo = item.BatchNo;
                        m.CreateDate = DateTime.Now;
                        m.RoutewayId = item.RoutewayId;
                        Context.TShippingLockCells.Add(m);

                        // 添加货品表
                        TShippingGoodsDetail product = new TShippingGoodsDetail();
                        product.OrderDetailId = model.Id;
                        product.MaterialId = item.MaterialId;
                        product.MaterialCode = item.MaterialCode;
                        product.MaterialName = item.MaterialName;
                        product.Status = 0;
                        product.PalletBarcode = item.PalletBarcode;
                        Context.TShippingGoodsDetails.Add(product);

                        Context.SaveChanges();
                    }

                    //无异常提交事务
                    tran.Commit();
                    return true;
                }
                catch (Exception)
                {
                    //事务回滚
                    tran.Rollback();
                    throw;
                }
            }
        }

        /// <summary>
        /// 添加出库管理 多个物料版本
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddTShippingOrderDetailPlus(TShippingOrderDetailPlusDTO model,out string msg)
        {
            msg = "添加出库单成功";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    if (model.OrderSn.Length!=9)
                    {
                        msg = "单号格式有误,必须为9位";
                        return false;
                    }
                    var orderSnIsHove = Context.TShippingOrderDetails.Where(s => s.OrderSn == model.OrderSn);
                    if (orderSnIsHove!=null && orderSnIsHove.Count()>0)
                    {
                        msg = "单号已存在";
                        return false;
                    }
                    if (string.IsNullOrEmpty(model.CarCode))
                    {
                        msg = "车牌号不能为空";
                        return false;
                    }
                    //var stationObj = Context.TStations.Find(model.StationId);
                    //if (stationObj == null)
                    //{
                    //    msg = "站台查询不到";
                    //    return false;
                    //}
                    //if (stationObj.Status == 0)
                    //{
                    //    msg = "站台已被禁用";
                    //    return false;
                    //}
                   
                    foreach (var mater in model.ShippingOrderDetailPlusLockCellDTOs)
                    {
          
                        //客户
                        var cust = Context.TCustomers.Find(model.CustomerId);
                        if (cust == null)
                        {
                            tran.Rollback();
                            msg = "找不到客户";
                            return false;
                        }

                        if (cust.MengNiuStatus == false)
                        {
                            tran.Rollback();
                            msg = "客户已被禁用";
                            return false;
                        }

                        //为了查询物料typeCode
                        var material = Context.TMaterials.FirstOrDefault(m=>m.Code==mater.MaterialCode);
                        if (material == null)
                        {
                            tran.Rollback();
                            msg = "找不到此物料";
                            return false;
                        }

                        var invmter = Context.TInventories.Where(m => m.MaterialCode == mater.MaterialCode);
                        if (invmter == null || invmter.Count() <= 0)
                        {
                            tran.Rollback();
                            msg = "库存中没有此物料";
                            return false;
                        }

                        var lockCell = lockCellRepository.LockCell(mater.MaterialCode, mater.MaterialNum, out var lockCellList, out var errorMsg);
                        if (!lockCell)
                        {
                            tran.Rollback();
                            msg = errorMsg;
                            return false;
                        }

                        var shippingOrderDetail = new TShippingOrderDetail
                        {
                            OrderSn = model.OrderSn, //同一个订单号
                            CustomerId = cust.Id, 
                            CustomerName = cust.Name,
                            MaterialId = material.Id,
                            MaterialName = mater.MaterialName,
                            MaterialTypeCode = material.TypeCode,
                            BillType = model.BillType,
                            WarehouseId = lockCellList[0].Id,
                            WarehouseCode = "",
                            WarehouseName = "",
                            AreaCode = "",
                            AreaName = "",
                            BatchNo = "",
                            UnitName = material.UnitName,
                            Qty = mater.MaterialNum,
                            Status = 0,
                            CreateDate = DateTime.Now,
                            CreateUserName = model.NowUserRealName,
                            CreateUserId = model.NowUserId,
                            CarCord=model.CarCode,
                            StationId=0,
                            StationName="测试站台"
                        };
                        Context.TShippingOrderDetails.Add(shippingOrderDetail);
                        if (Context.SaveChanges() <= 0)
                        {
                            msg = "出库单添加失败,单号："+model.OrderSn;
                            tran.Rollback();
                            return false;
                        }

                        // 添加货品表
                        //var product = new TShippingGoodsDetail
                        //{
                        //    OrderDetailId = shippingOrderDetail.Id,
                        //    MaterialId = mater.MaterialId,
                        //    MaterialCode = mater.MaterialCode,
                        //    MaterialName = mater.MaterialName,
                        //    Status = 0
                        //};
                        //Context.TShippingGoodsDetails.Add(product);
                        //Context.SaveChanges();

                        //货位锁定明细
                        foreach (var item in lockCellList)
                        {
                            var inv = Context.TInventories.Where(s => s.Id == item.InventoryId).FirstOrDefault();
                            if (inv == null)
                            {
                                msg = "找不到库存,库存id:" + item.InventoryId;
                                tran.Rollback();
                                return false;
                            }
                            inv.Status = 4;
                            Context.TInventories.Update(inv);
                            //货位锁定明细
                            var m = new TShippingLockCell
                            {
                                OrdeSn= model.OrderSn,
                                OrderDetailId = shippingOrderDetail.Id,
                                InventoryId = item.InventoryId,
                                CellId = item.CellId,
                                CellCode = item.CellCode,
                                CellName = item.CellName,
                                PalletBarcode = item.PalletBarcode,
                                WhId = item.WhId,
                                CellDepthIndex = 0,
                                StackingStorageId = item.StackingStorageId,
                                OutQty = item.OutQty,
                                InventoryQty = item.InventoryQty,
                                MaterialId = material.Id,
                                MaterialName = item.MaterialName,
                                MaterialCode = item.MaterialCode,
                                MaterialKeyId = item.MaterialKeyId,
                                BatchNo = item.BatchNo,
                                SmallBatchNo = item.SmallBatchNo,
                                CreateDate = DateTime.Now,
                                RoutewayId = item.RoutewayId,
                                IsPicking = false
                            };
                            Context.TShippingLockCells.Add(m);
                            if (Context.SaveChanges() <= 0)
                            {
                                msg = "出库单明细添加失败,物料："+item.MaterialName+",单号："+model.OrderSn;
                                tran.Rollback();
                                return false;
                            }
                        }
                    }
                    //无异常提交事务
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //事务回滚
                    msg = "catch:" + ex.Message;
                    tran.Rollback();
                    return false;
                }
            }
        }

        /// <summary>
        /// 删除出库表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        //public bool DeleteTShippingOrderDetail(int id)
        public bool DeleteTShippingOrderDetail(string OrderSn,out string errorMsg)
        {
            errorMsg = string.Empty;
            using var tran = Context.Database.BeginTransaction();
            try
            {
                var deleteModel = Context.TShippingOrderDetails.Where(x => x.OrderSn == OrderSn);
                //var delShip = Context.TShippingLockCells.Where(s => s.OrderDetailId == id);
                if (deleteModel == null || deleteModel.Count()<=0)
                {
                    errorMsg = "找不到要删除的出库单，单号："+OrderSn;
                    return false;
                }
                if (deleteModel.Any(s => s.Status != 0))
                {
                    errorMsg = "出库单不是创建状态无法删除，单号：" + OrderSn;
                    return false;
                }
                int lockCellId = 0;
                int ?inventoryId = 0;
                var updInvList = new List<TInventory>();
                var lockCellList = Context.TShippingLockCells.Where(x => x.OrdeSn == OrderSn).ToList();
                foreach (var lockCell in lockCellList.ToList())
                {
                    lockCellId = lockCell.Id;
                    inventoryId = lockCell.InventoryId;
                    if (inventoryId <= 0)
                    {
                        continue;
                    }
                    // 修改库存状态
                    var invs = Context.TInventories.Find(inventoryId);
                    if (invs != null)
                    {
                        invs.Status = 1;
                        updInvList.Add(invs);
                        Context.TInventory.UpdateRange(updInvList);
                        if (Context.SaveChanges() <= 0)
                        {
                            errorMsg = "删除出库单时,库存信息修改失败,库存ID为:" + invs.Id;
                            tran.Rollback();
                            return false;
                        }
                    }

                    // 删除TShippingLockCells表数据
                    Context.TShippingLockCells.Remove(lockCell);
                    if (Context.SaveChanges() <= 0)
                    {
                        errorMsg = "删除仓位锁定表数据失败,仓位锁定ID为:" + lockCell.Id;
                        tran.Rollback();
                        return false;
                    }

                }
                // 删除TShippingOrderDetails
                Context.TShippingOrderDetails.RemoveRange(deleteModel);
                if (Context.SaveChanges() <= 0)
                {
                    errorMsg = "删除出库单明细表数据失败，出库单号:"+OrderSn;
                    tran.Rollback();
                    return false;
                }
                tran.Commit();
                return true;
  
            }
            catch (Exception ex)
            {
                errorMsg = "删除出库单catch:" + ex.Message;
                //事务回滚
                tran.Rollback();
                return false;
            }
        }

        // 根据OrderSn查询ID
        private List<int> GetTShippingOrderDetailId (string OrderSn)
        {
            List<int> listInt = new List<int>();

            var list = Context.TShippingOrderDetails.Where(x => x.OrderSn == OrderSn);

            if (list == null)
            {
                return listInt;
            }
            foreach (var item in list)
            {
                listInt.Add(item.Id);
            }
            return listInt;
        }


        /// <summary>
        /// 修改出库单  多物料版本
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdateTshippingOrderDetailPlus(TShippingOrderDetailPlusDTO models, out string errorMsg)
        {
            errorMsg = "修改了出库单";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    var updateModelList = Context.TShippingOrderDetails.Where(x => x.OrderSn ==  models.OrderSn);
                    if (updateModelList == null || updateModelList.Count() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "要更新的出库单不存在,出库单号："+models.OrderSn;
                        return false;
                    }
                    //先把出库单中的明细都删除
                    var delOutOrderId = Context.TShippingOrderDetails.Where(s=>s.OrderSn==models.OrderSn).Select(s=>s.Id);
                    var delLockCell = Context.TShippingLockCells.Where(s=>s.OrdeSn==models.OrderSn); //要删除的所有LockCell
                    if (GetStatus(delLockCell.ToList()) != "创建")
                    {
                        tran.Rollback();
                        errorMsg = "出库单不是创建状态";
                        return false;
                    }
                    if (delLockCell == null || delLockCell.Count() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "仓位锁定表查询失败";
                        return false;
                    }
                    var updInvId = delLockCell.Select(s => s.InventoryId).ToList();
                    var updInvInLockCelll = Context.TInventories.Where(s=> updInvId.Contains(s.Id));//要更改状态的库存
                    if (updInvInLockCelll == null || updInvInLockCelll.Count() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "库存表查询失败";
                        return false;
                    }
                    foreach (var item in updInvInLockCelll)
                    {
                        item.Status = 1;
                    }
                    Context.UpdateRange(updInvInLockCelll);//修改库存
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "库存状态修改失败";
                        return false;
                    }
                    Context.RemoveRange(updateModelList);//删除出库单
                    if (Context.SaveChanges() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "出库单删除失败";
                        return false;
                    }
                    //Context.RemoveRange(delLockCell);//仓位锁定表 不知道为什么RemoveRange不管用
                    //if (Context.SaveChanges() <= 0)
                    //{
                    //    tran.Rollback();
                    //    errorMsg = "仓位锁定表删除失败";
                    //    return false;
                    //}
                    foreach (var item in delLockCell)
                    {
                        Context.Remove(item);
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "仓位锁定表删除失败";
                            return false;
                        }
                    }
                    //添加出库单明细 仓位锁定表
                    foreach (var item in models.ShippingOrderDetailPlusLockCellDTOs)
                    {
                        //客户
                        var cust = Context.TCustomers.Find(models.CustomerId);
                        if (cust == null)
                        {
                            tran.Rollback();
                            errorMsg = "找不到客户";
                            return false;
                        }
                        //为了查询物料typeCode
                        var material = Context.TMaterials.FirstOrDefault(m => m.Code == item.MaterialCode);
                        if (material == null)
                        {
                            tran.Rollback();
                            errorMsg = "找不到此物料";
                            return false;
                        }

                        //查找库存
                        var invmter = Context.TInventories.Where(s => s.MaterialCode == item.MaterialCode);
                        if (invmter == null || invmter.Count() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "库存中没有此物料";
                            return false;
                        }
                        //分配出库仓位
                        var lockCellRes = lockCellRepository.LockCell(item.MaterialCode, item.MaterialNum, out var addLockCellList, out var lockerrorMsg);
                        if (!lockCellRes)
                        {
                            tran.Rollback();
                            errorMsg = lockerrorMsg;
                            return false;
                        }
                        TShippingOrderDetail shippingOrderDetail = new TShippingOrderDetail
                        {
                            OrderSn = models.OrderSn, //同一个订单号
                            CustomerId = cust.Id,  // 拿供应商当客户用！
                            CustomerName = cust.Name,
                            CarCord=models.CarCode,
                            MaterialId = item.MaterialId,
                            MaterialName = item.MaterialName,
                            MaterialTypeCode = material.TypeCode,
                            BillType = models.BillType,
                            WarehouseCode = "",
                            WarehouseName = "",
                            AreaCode = "",
                            AreaName = "",
                            BatchNo = "",
                            UnitName = material.UnitName,
                            Qty = item.MaterialNum,
                            Status = 0,
                            StationName = "",
                            CreateDate = DateTime.Now,
                            CreateUserName = "",
                            CreateUserId = 0
                        };
                        Context.TShippingOrderDetails.Add(shippingOrderDetail);
                        Context.SaveChanges();
                        //货位锁定明细
                        foreach (var addLockCell in addLockCellList)
                        {
                            var inv = Context.TInventories.Where(s => s.Id == addLockCell.InventoryId).FirstOrDefault();
                            if (inv == null)
                                return false;
                            inv.Status = 4;
                            Context.TInventories.Update(inv);
                            //货位锁定明细
                            TShippingLockCell m = new TShippingLockCell
                            {
                                OrdeSn=models.OrderSn,
                                OrderDetailId = shippingOrderDetail.Id,
                                InventoryId = addLockCell.InventoryId,
                                CellId = addLockCell.CellId,
                                CellCode = addLockCell.CellCode,
                                CellName = addLockCell.CellName,
                                PalletBarcode = addLockCell.PalletBarcode,
                                WhId = addLockCell.WhId,
                                CellDepthIndex = 0,
                                StackingStorageId = addLockCell.StackingStorageId,
                                OutQty = addLockCell.OutQty,
                                InventoryQty = addLockCell.InventoryQty,
                                MaterialId = item.MaterialId,
                                MaterialName = item.MaterialName,
                                MaterialCode = item.MaterialCode,
                                MaterialKeyId = addLockCell.MaterialKeyId,
                                BatchNo = addLockCell.BatchNo,
                                SmallBatchNo = addLockCell.SmallBatchNo,
                                CreateDate = DateTime.Now,
                                RoutewayId = addLockCell.RoutewayId,
                                IsPicking = false
                            };
                            Context.TShippingLockCells.Add(m);
                            Context.SaveChanges();
                        }
                    }

                    //无异常提交事务
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    errorMsg = "cacth:"+ex.Message;
                    return false;
                }
            }
        }


        /// <summary>
        /// 修改出库单 有问题先不用
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdateTshippingOrderDetailPlusNew(TShippingOrderDetailPlusDTO models, out string errorMsg)
        {
            var customerObj = Context.TCustomers.FirstOrDefault(s=>s.Id==models.CustomerId);
            if (customerObj == null)
            {
                errorMsg = "要更新的客户不存在";
                return false;
            }
 
            errorMsg = "修改了出库单";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    //出库单
                    var outHouseList = Context.TShippingOrderDetails.Where(x => x.OrderSn == models.OrderSn).ToList();
                    if (outHouseList == null || outHouseList.Count() <= 0)
                    {
                        tran.Rollback();
                        errorMsg = "要更新的出库单不存在,出库单号：" + models.OrderSn;
                        return false;
                    }

                    //出库单明细
                    var dataDetailList = Context.TShippingLockCells
                                                .Where(s => s.OrdeSn == models.OrderSn)
                                                .GroupBy(s => s.OrderDetailId)
                                                .Select(g => new TShippingOrderDetailPlusLockCellDTO(g.First().Id,g.First().MaterialId.GetValueOrDefault(),g.First().MaterialName,g.First().MaterialCode,(int)g.First().OutQty.GetValueOrDefault()))
                                                .ToList();


                    //将数据库中的数据转化为DTO类型 入参
                    var dataInDTO =new TShippingOrderDetailPlusDTO();
                    dataInDTO.OrderSn= outHouseList[0].OrderSn;
                    dataInDTO.CustomerId = outHouseList[0].CustomerId.GetValueOrDefault();
                    dataInDTO.CarCode = outHouseList[0].CarCord;
                    dataInDTO.BillType = outHouseList[0].BillType.GetValueOrDefault();
                    dataInDTO.AreaName = models.AreaName;
                    dataInDTO.Timestamp = models.Timestamp;
                    dataInDTO.ShippingOrderDetailPlusLockCellDTOs = dataDetailList;
                    //出库单无修改
                    if (dataInDTO.OrderSn == models.OrderSn &&
    dataInDTO.CustomerId == models.CustomerId &&
    dataInDTO.CarCode == models.CarCode &&
    dataInDTO.BillType == models.BillType &&
    dataInDTO.AreaName == models.AreaName &&
    dataInDTO.Timestamp == models.Timestamp && dataInDTO.ShippingOrderDetailPlusLockCellDTOs.SequenceEqual(models.ShippingOrderDetailPlusLockCellDTOs))
                    {
                        tran.Rollback();
                        errorMsg = "出库单无修改,出库单号：" + models.OrderSn;
                        return true;
                    }

                    //判断出库单有没有更改
                    if (models.BillType != dataInDTO.BillType || models.CarCode != dataInDTO.CarCode || models.CustomerId != dataInDTO.CustomerId)
                    {
                        foreach (var item in outHouseList)
                        {
                            item.BillType = dataInDTO.BillType;
                            item.CarCord = dataInDTO.CarCode;
                            item.CustomerId= dataInDTO.CustomerId;
                        }
                        Context.UpdateRange(outHouseList);//修改出库单
                        if (Context.SaveChanges() <= 0)
                        {
                            tran.Rollback();
                            errorMsg = "出库单修改失败";
                            return false;
                        }
                    }
                    //判断DTO出库单明细有没有更改
                    foreach (var dto in models.ShippingOrderDetailPlusLockCellDTOs)
                    {
                        //为了查询物料typeCode
                        var material = Context.TMaterials.Find(dto.MaterialId);
                        if (material == null)
                        {
                            tran.Rollback();
                            errorMsg = "找不到此物料";
                            return false;
                        }
               
                        //如果在入参中明细id=-1,则添加明细,和前段约定好
                        if (dto.TShippingLockCellsId == -1)
                        {
                            var outHouseAdd = new TShippingOrderDetail()
                            {
                                OrderSn = models.OrderSn, //同一个订单号
                                CustomerId = outHouseList[0].Id,  // 拿供应商当客户用！
                                CustomerName = customerObj.Name,
                                CarCord = models.CarCode,
                                MaterialId = material.Id,
                                MaterialName = material.Name,
                                MaterialTypeCode = material.TypeCode,
                                BillType = models.BillType,
                                WarehouseCode = "",
                                WarehouseName = "",
                                AreaCode = "",
                                AreaName = "",
                                BatchNo = "",
                                UnitName = material.UnitName,
                                Qty = dto.MaterialNum,
                                Status = 0,
                                StationName = "",
                                CreateDate = DateTime.Now,
                                CreateUserName = "",
                                CreateUserId = 0
                            };
                            Context.TShippingOrderDetails.Add(outHouseAdd);
                            if (Context.SaveChanges() <= 0)
                            {
                                tran.Rollback();
                                errorMsg = "出库单修改失败";
                                return false;
                            }
                            //分配仓位
                            var lockCellRes = lockCellRepository.LockCell(dto.MaterialCode, dto.MaterialNum, out var addLockCellList, out var lockerrorMsg);
                            if (!lockCellRes)
                            {
                                tran.Rollback();
                                errorMsg = lockerrorMsg;
                                return false;
                            }
                            foreach (var addLockCell in addLockCellList)
                            {
                                var inv = Context.TInventories.Where(s => s.Id == addLockCell.InventoryId).FirstOrDefault();
                                if (inv == null)
                                    return false;
                                inv.Status = 4;
                                Context.TInventories.Update(inv);
                                var m = new TShippingLockCell
                                {
                                    OrdeSn = models.OrderSn,
                                    OrderDetailId = outHouseAdd.Id,
                                    InventoryId = addLockCell.InventoryId,
                                    CellId = addLockCell.CellId,
                                    CellCode = addLockCell.CellCode,
                                    CellName = addLockCell.CellName,
                                    PalletBarcode = addLockCell.PalletBarcode,
                                    WhId = addLockCell.WhId,
                                    CellDepthIndex = 0,
                                    StackingStorageId = addLockCell.StackingStorageId,
                                    OutQty = addLockCell.OutQty,
                                    InventoryQty = addLockCell.InventoryQty,
                                    MaterialId = dto.MaterialId,
                                    MaterialName = dto.MaterialName,
                                    MaterialCode = dto.MaterialCode,
                                    MaterialKeyId = addLockCell.MaterialKeyId,
                                    BatchNo = addLockCell.BatchNo,
                                    SmallBatchNo = addLockCell.SmallBatchNo,
                                    CreateDate = DateTime.Now,
                                    RoutewayId = addLockCell.RoutewayId,
                                    IsPicking = false
                                };
                                Context.TShippingLockCells.Add(m);
                                Context.SaveChanges();
                            }
                        }
                    }
                    //循环数据库中的出库单明细
                    foreach (var data in dataInDTO.ShippingOrderDetailPlusLockCellDTOs)
                    {
                        //如果没找到入参的id在数据库中对应的数据,就证明是删了
                        var dataDetail = models.ShippingOrderDetailPlusLockCellDTOs.FirstOrDefault(s => s.TShippingLockCellsId == data.TShippingLockCellsId);
                        if (dataDetail == null)
                        {
                            var removeObj = Context.TShippingLockCells.FirstOrDefault(s => s.Id == data.TShippingLockCellsId);
                            if (removeObj == null)
                            {
                                tran.Rollback();
                                errorMsg = "修改失败，找不到出库单明细id:"+data.TShippingLockCellsId;
                                return false;
                            }
                            Context.Remove(removeObj);//删除出库单
                            if (Context.SaveChanges() <= 0)
                            {
                                tran.Rollback();
                                errorMsg = "出库单删除失败";
                                return false;
                            }
                        }
                        //如果找到了判断数量有没有修改
                        else if (dataDetail != null)
                        {
    
                            //如果入参数量不等于数据库中的数量进行修改 重新给物料分配仓位
                            if (dataDetail.MaterialNum != data.MaterialNum)
                            {
                                var updObj = Context.TShippingLockCells.FirstOrDefault(s => s.Id == data.TShippingLockCellsId);
                                if (updObj == null)
                                {
                                    tran.Rollback();
                                    errorMsg = "修改失败，找不到出库单明细id:" + data.TShippingLockCellsId;
                                    return false;
                                }
                                List<TShippingLockCell> addLockCellList = new List<TShippingLockCell>();
                                var loceCellRes = lockCellRepository.LockCell(updObj.MaterialCode,data.MaterialNum,out addLockCellList, out var lockCellMsg);
                                if (!loceCellRes)
                                {
                                    errorMsg = lockCellMsg;
                                    tran.Rollback();
                                    return false;
                                }
                                
                                //修改分配到的仓位的库存状态
                                var updInvId = addLockCellList.Select(s => s.InventoryId).ToList();
                                var updInvInLockCelll = Context.TInventories.Where(s => updInvId.Contains(s.Id));//要更改状态的库存
                                if (updInvInLockCelll == null || updInvInLockCelll.Count() <= 0)
                                {
                                    tran.Rollback();
                                    errorMsg = "库存表查询失败";
                                    return false;
                                }
                                foreach (var item in updInvInLockCelll)
                                {
                                    item.Status = 1;
                                }
                                Context.UpdateRange(updInvInLockCelll);//修改库存
                                if (Context.SaveChanges() <= 0)
                                {
                                    tran.Rollback();
                                    errorMsg = "库存状态修改失败";
                                    return false;
                                }


                                //货位锁定明细
                                foreach (var addLockCell in addLockCellList)
                                {
                                    //货位锁定明细
                                    TShippingLockCell m = new TShippingLockCell
                                    {
                                        OrdeSn=models.OrderSn,
                                        OrderDetailId = updObj.OrderDetailId,
                                        InventoryId = addLockCell.InventoryId,
                                        CellId = addLockCell.CellId,
                                        CellCode = addLockCell.CellCode,
                                        CellName = addLockCell.CellName,
                                        PalletBarcode = addLockCell.PalletBarcode,
                                        WhId = addLockCell.WhId,
                                        CellDepthIndex = 0,
                                        StackingStorageId = addLockCell.StackingStorageId,
                                        OutQty = addLockCell.OutQty,
                                        InventoryQty = addLockCell.InventoryQty,
                                        MaterialId = updObj.MaterialId,
                                        MaterialName = updObj.MaterialName,
                                        MaterialCode = updObj.MaterialCode,
                                        MaterialKeyId = addLockCell.MaterialKeyId,
                                        BatchNo = addLockCell.BatchNo,
                                        SmallBatchNo = addLockCell.SmallBatchNo,
                                        CreateDate = DateTime.Now,
                                        RoutewayId = addLockCell.RoutewayId,
                                        IsPicking = false
                                    };
                                    Context.TShippingLockCells.Add(m);
                                    if (Context.SaveChanges() <= 0)
                                    {
                                        tran.Rollback();
                                        errorMsg = "库存明细添加失败";
                                        return false;
                                    }
                                }
                            }
                        }
                    }
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    errorMsg = "cacth:" + ex.Message;
                    return false;
                }
            }
        }




        /// <summary>
        /// 修改状态
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool UpdTShippingOrderDetailState(ReceivingOrderDetailDto model)
        {
            var robjs = Context.TShippingOrderDetails.Where(s=>s.OrderSn==model.OrderSN).ToList();

            if (robjs != null && robjs.Count()!=0)
            {
                foreach (var robj in robjs)
                {
                    switch (model.state)
                    {
                        case 0:
                            var uobj = Context.TUsers.FirstOrDefault(x =>
                                x.Id == model.NowUserId && x.JobNo == model.JobNo);
                            if (uobj != null)
                            {
                                robj.SubmitUserId = model.NowUserId;
                                robj.SubmitUserName = model.NowUserRealName;
                                robj.SubmitDate = DateTime.Now;

                                //修改为：审核通过
                                robj.Status = 2;
                                Context.TShippingOrderDetails.Update(robj);
                                break;
                            }

                            return false;

                        case 1:
                            break;

                        case 2:
                            robj.ModifyUserId = model.NowUserId;
                            robj.ModifyUserName = model.NowUserRealName;
                            robj.ModifyDate = DateTime.Now;
                            //修改为：作业中
                            robj.Status = 3;
                            Context.TShippingOrderDetails.Update(robj);
                            break;

                        case 3:
                            robj.ModifyUserId = model.NowUserId;
                            robj.ModifyUserName = model.NowUserRealName;
                            robj.ModifyDate = DateTime.Now;
                            //修改为：已完成
                            robj.Status = 4;
                            Context.TShippingOrderDetails.Update(robj);
                            break;

                        default:
                            break;
                    }
                }

                return Context.SaveChanges() > 0;
            }

            return false;
        }

        /// <summary>
        /// 一键选定(弃用)
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public bool SelectTShippingOrderDetail(TShippingOrderDetail model)
        {
            var OrderDetail = Context.TShippingOrderDetails.FirstOrDefault(m =>
                m.MaterialId == model.MaterialId &&
                m.WarehouseId == model.WarehouseId && m.BatchNo == model.BatchNo && m.Qty == model.Qty);
            if (OrderDetail == null)
            {
                return false; // 找不到对应的出库管理记录，选定失败
            }
            // 设置其他相关字段值，例如物料分类、物料名称、物料批次等

            OrderDetail.MaterialName = model.MaterialName;
            OrderDetail.WarehouseName = model.WarehouseName;
            OrderDetail.BatchNo = model.BatchNo;
            OrderDetail.Qty = model.Qty;
            OrderDetail.MaterialCode = model.MaterialCode;
            OrderDetail.StationId = model.StationId;
            OrderDetail.StationName = model.StationName;
            OrderDetail.OwnerId = model.OwnerId;
            OrderDetail.OwnerName = model.OwnerName;
            OrderDetail.AreaName = model.AreaName;
            OrderDetail.AreaCode = model.AreaCode;
            OrderDetail.ContractNo = model.ContractNo;
            OrderDetail.BillType = model.BillType;
            OrderDetail.DisOrderLineNo = model.DisOrderLineNo;
            OrderDetail.SupplierId = model.SupplierId;
            OrderDetail.SupplierName = model.SupplierName;
            OrderDetail.AuditUserId = model.AuditUserId;
            OrderDetail.AuditUserName = model.AuditUserName;
            OrderDetail.Status = model.Status;
            // 保存修改
            Context.SaveChanges();

            // 创建新的TShippingLockCell实例并赋值
            List<TShippingLockCell> lockCells = new List<TShippingLockCell>();

            //库位
            var Cells = Context.TCells.FirstOrDefault(m => lockCells.Any(x => x.CellId == m.Id));
            //出库详细单
            var orderDetail =
                Context.TShippingOrderDetails.FirstOrDefault(m => lockCells.Any(x => x.OrderDetailId == m.Id));
            //库存
            var inventory = Context.TInventories.FirstOrDefault(m => lockCells.Any(x => x.InventoryId == m.Id));

            if (new TShippingLockCell().InventoryQty >= model.Qty)
            {
                var lockCell = new TShippingLockCell
                {
                    MaterialId = OrderDetail.MaterialId,
                    MaterialCode = model.MaterialCode,
                    MaterialName = model.MaterialName,
                    OrderDetailId = model.Id,
                    OutQty = OrderDetail.Qty,
                    CellName = Cells.Name,
                    WhId = OrderDetail.WarehouseId,
                    InventoryId = inventory.Id,
                    InventoryQty = inventory.AvailableQty,
                    BatchNo = OrderDetail.BatchNo
                };
                lockCells.Add(lockCell);
            }
            else
            {
                // 根据出库数量创建多个TShippingLockCell实例并添加到列表中
                decimal? remainingQty = model.Qty;
                decimal? stockQuantity = inventory.AvailableQty;
                while (remainingQty > 0)
                {
                    var lockCellss = new TShippingLockCell
                    {
                        MaterialId = OrderDetail.MaterialId,
                        MaterialCode = model.MaterialCode,
                        MaterialName = model.MaterialName,
                        OrderDetailId = model.Id,
                        OutQty = OrderDetail.Qty,
                        CellName = Cells.Name,
                        WhId = OrderDetail.WarehouseId,
                        InventoryId = inventory.Id,
                        BatchNo = OrderDetail.BatchNo,
                        InventoryQty = Math.Min(stockQuantity ?? 0, remainingQty ?? 0),
                    };

                    lockCells.Add(lockCellss);

                    remainingQty -= stockQuantity; // 更新剩余数量
                }
            }

            Context.TShippingLockCells.AddRange(lockCells);

            return Context.SaveChanges() > 0;
        }

        /// <summary>
        /// 一键选定（弃用）
        /// </summary>
        /// <param name="qty"></param>
        /// <param name="inventoryId"></param>
        /// <param name="whId"></param>
        /// <param name="materialId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TShippingLockCell> GetAllTShippingLockCell(TShippingOrderDetail model)
        {
            // 校验物料Id是否为空或无效
            if (model.MaterialId <= 0)
            {
                throw new ArgumentException("请选择物料");
            }

            // 校验数量是否为空或无效
            if (model.Qty <= 0)
            {
                throw new ArgumentException("请选择出库数量");
            }

            if (model.WarehouseId <= 0)
            {
                throw new ArgumentException("请选择仓库");
            }

            if (model.MaterialId <= 0)
            {
                throw new ArgumentException("请选择物料");
            }

            List<TShippingLockCell> selectedCells = new List<TShippingLockCell>();
            // 查询仓位明细表中符合条件的数据
            var query = from cell in Context.TShippingLockCells
                        where cell.InventoryQty >= model.Qty && cell.WhId == model.WarehouseId &&
                              cell.MaterialId == model.MaterialId

                        select cell;

            // 遍历查询结果，并将符合条件的仓位明细添加到返回列表中
            foreach (var cell in query)
            {
                selectedCells.Add(cell);
            }

            return selectedCells;
        }

        /// <summary>
        /// 显示
        /// </summary>
        /// <param name="status"></param>
        /// <param name="houseid"></param>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TShippingOrderDetail> GetAllTShippingOrderDetail(int? billType, int? houseid, string? name,
            int pageIndex, int pageSize, out int totalCount)
        {
            // 创建查询的基础列表，包含所有的 TShippingOrderDetail 记录
            var query = Context.TShippingOrderDetails.AsQueryable();

            // 根据传入的参数进行筛选
            if (billType.HasValue && billType.Value != 0)
            {
                query = query.Where(m => m.BillType == billType);
            }

            if (houseid.HasValue && houseid.Value != 0)
            {
                query = query.Where(m => m.WarehouseId == houseid);
            }

            if (!string.IsNullOrEmpty(name))
            {
                query = query.Where(m => m.MaterialName == name);
            }

            // 获取符合条件的总记录数
            totalCount = query.Count();

            // 对结果进行排序和分页
            var resultList = query.OrderByDescending(m => m.CreateDate)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToList();

            return resultList;
        }

        /// <summary>
        /// 根据物料Id返回批次号和数量
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public BatchNoMaxCount GetMaterialIdById(int materialId, string batchNO = null, int? qualityState = null, string warehouseCode = "", string areaCode = "", int? ownerId = null, int? supplierId = null, string produceFactory = "")
        {
            //数量
            try
            {
                BatchNoMaxCount bc = new BatchNoMaxCount();

                //找出该库存的所有批次号
                var materialKeyQuery = Context.TMaterialKeys;
                var inventoryQuery = Context.TInventories;

                var list=(from mk in materialKeyQuery
                         join inv in inventoryQuery
                         on mk.Id equals inv.MaterialKeyId
                         where mk.MaterialId == materialId
                         select new BatchNoMaxCountDTO ( mk.BatchNo,mk.Id)).Distinct().ToList();
                bc.materialKeys = list;

                //仓位状态 货架状态 巷道状态
                var cellQuery = Context.TCells;
                var shelfQuery = Context.TShelves;
                var routewayQuery = Context.TRouteways;
                var TInventoryQuery = (from inv in Context.TInventories
                                       join cell in cellQuery
                                       on inv.LocationCode equals cell.Code
                                       join slf in shelfQuery
                                       on cell.ShelfCode equals slf.Code
                                       join rtw in routewayQuery
                                       on cell.RoutewayId equals rtw.Id
                                       where cell.Status == 1 && slf.Status == 1 && rtw.Status == 1
                                       select inv).ToList();
                //var TInventoryQuery = (from inv in Context.TInventories
                //                       join cell in cellQuery
                //                       on inv.LocationId equals cell.Id
                //                       join slf in shelfQuery
                //                       on cell.ShelfId equals slf.Id
                //                       join rtw in routewayQuery
                //                       on cell.RoutewayId equals rtw.Id
                //                       select inv
                //                      ).ToList();

                var invList = TInventoryQuery.Where(t => t.MaterialId == materialId && t.Status == 1 && t.IsLock == false).ToList();
                if (!string.IsNullOrEmpty(batchNO))
                {
                    invList = invList.Where(t => t.BatchNo == batchNO).ToList();
                }
                if (qualityState != null)
                {
                    invList = invList.Where(t => t.QualityState == qualityState).ToList();
                }
                if (!string.IsNullOrEmpty(warehouseCode))
                {
                    invList = invList.Where(t => t.WarehouseCode == warehouseCode).ToList();
                }
                if (!string.IsNullOrEmpty(areaCode))
                {
                    invList = invList.Where(t => t.AreaCode == areaCode).ToList();
                }
                if (ownerId > 0)
                {
                    invList = invList.Where(t => t.OwnerId == ownerId).ToList();
                }
                if (supplierId > 0)
                {
                    invList = invList.Where(t => t.SupplierId == supplierId).ToList();
                }
                if (!string.IsNullOrEmpty(produceFactory))
                {
                    invList = invList.Where(t => t.ProduceFactory.Contains(produceFactory)).ToList();
                }
                decimal? sum = invList.Sum(t => t.AvailableQty);

                List<int?> status = new List<int?>
                {
                    (int)EmBillStatus.Create,
                    (int)EmBillStatus.Submit,
                    (int)EmBillStatus.Pass,
                };
                //一键出库优先级最高
                var shippingOrderDetailQuery = Context.TShippingOrderDetails.OrderByDescending(t => t.IsOnceOut);
                var slcOdQuery = (from lockCell in Context.TShippingLockCells
                                  join od in shippingOrderDetailQuery
                                  on lockCell.OrderDetailId equals od.Id
                                  select new { lockCell, od }
                                ).ToList();
                var slcOdQueryTest = slcOdQuery.ToList();
                List<TShippingLockCell> lockCells = slcOdQuery.Select(x => x.lockCell).ToList();
                List<TShippingOrderDetail> orderDetails = slcOdQuery.Select(x => x.od).ToList();
                orderDetails = orderDetails.Where(od => od.MaterialId == materialId && status.Contains(od.Status)).ToList();
                lockCells = lockCells.Where(loc => loc.MaterialId == materialId).ToList();
                slcOdQuery = (from lockCell in lockCells
                                join od in orderDetails
                                on lockCell.OrderDetailId equals od.Id
                                select new { lockCell, od }
                        ).ToList();
                

                //剔除被锁定的库存
                var lockInvIdQuery = (from lockCell in lockCells
                                      join od in orderDetails
                                      on lockCell.OrderDetailId equals od.Id
                                      select lockCell.InventoryId
                            ).Distinct().ToList();
                int lockInvCount = lockInvIdQuery.Count();
                if (lockInvCount > 0)
                {
                    invList = invList.Where(t => !lockInvIdQuery.ToList().Contains(t.Id)).ToList();
                }
                //查出所有匹配的库存
                List<TInventory> TInventoryList = invList.OrderBy(x => x.LocationDepth)
                                                        .ThenBy(x => x.InStockShortDate)
                                                        .ThenByDescending(x => x.AvailableQty)
                                                        .ThenBy(x => x.LocationLineNo)
                                                        .ThenBy(x => x.LocationLayerNo)
                                                        .ThenBy(x => x.LocationColumnNo).ToList();
                //库存可用数量
                decimal totalTInventoryCount = TInventoryList.Sum(t => t.AvailableQty.GetValueOrDefault());
                //当前物料已出库多少

                bc.MaxCount = totalTInventoryCount;
                return bc;

            }
            catch (Exception ex)
            {
                throw ex;
            }
     
            //BatchNoMaxCount bc = new BatchNoMaxCount();
            ////物料批次
            //var mkobj = Context.TMaterialKeys.FirstOrDefault(x => x.MaterialId == mid);
            ////库存数量
            //var iobj = Context.TInventories.Where(x => x.MaterialId == mid);
            //if (iobj.Count() <= 0)
            //{
            //    return bc;
            //}

            //if (mkobj != null)
            //{
            //    bc.BatchNO.Add(mkobj.BatchNo);
            //}

            //if (iobj != null)
            //{
            //    foreach (var item in iobj.ToList())
            //    {
            //        bc.MaxCount += item.AvailableQty;
            //    }
            //}

            //return bc;
        }
         
        /// <summary>
        /// 一键选定
        /// </summary>
        /// <param name="materid">物料Id</param>
        /// <param name="count">出库数量</param>
        /// <param name="whid">库房Id</param>
        /// <param name="areaid">库区Id</param>
        /// <param name="supid">供应商Id</param>
        /// <param name="owid">货主Id</param>
        /// <returns></returns>
        public List<TInventory> GetAllTShippingLockCell(int materid, int count, int whid, int areaid, int supid,
            int owid)
        {
            //var shippinglockcell=Context.TShippingLockCells.Where(x=>x.)
            var ilist = Context.TInventories.Where(x => x.MaterialId == materid);
            ilist = ilist.Where(x => x.AvailableQty != 0 && x.Status==1);
            ilist = ilist.OrderBy(x => x.BatchNo);
            //库房
            if (whid != 0)
            {
                ilist = ilist.Where(x => x.WarehouseId == whid);
            }

            //库区
            if (areaid != 0)
            {
                ilist = ilist.Where(x => x.AreaId == areaid);
            }

            //供应商
            if (supid != 0)
            {
                ilist = ilist.Where(x => x.SupplierId == supid);
            }

            //货主
            if (owid != 0)
            {
                ilist = ilist.Where(x => x.OwnerId == owid);
            }

            List<TInventory> list = new List<TInventory>();
            //收货的数量
            foreach (var item in ilist)
            {
                //decimal? outqty = count - item.AvailableQty;
                if (count == item.AvailableQty)
                {
                    //如果要出库的数量等于该库存的数量则直接返回
                    item.OutQty = item.AvailableQty;
                    list.Add(item);
                    return list;
                }
                else if (count > item.AvailableQty)
                {
                    item.OutQty = item.AvailableQty;
                    list.Add(item);
                    count = Convert.ToInt32(count - item.OutQty);
                }
                else if (count < item.AvailableQty)
                {
                    item.OutQty = count;
                    list.Add(item);
                    return list;
                }
            }
            
            return list;
        }

        /// <summary>
        /// 获取商品详细
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<TShippingGoodsDetail> GetOneTShippingGoodsDetail(int id, int pageIndex, int pageSize, out int totalCount)
        {
            var order = Context.TShippingOrderDetails.Find(id);
            if (order == null)
            {
                totalCount = 0;
                // 订单不存在时返回一个空的列表
                return new List<TShippingGoodsDetail>();
            }
            var details = Context.TShippingGoodsDetails.Where(m => m.OrderDetailId == order.Id).ToList();
            // 获取符合条件的总记录数
            totalCount = details.Count();

            // 对结果进行排序和分页
            var resultList = details.OrderBy(m => m.CreateDate)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToList();
            return resultList;
        }

        public List<TShippingGoodsDetail> GetByNameShippingGoodsDetail(string? name, int pageIndex, int pageSize, out int totalCount)
        {
            var query = Context.TShippingGoodsDetails.AsQueryable();
            if (!string.IsNullOrEmpty(name))
            {
                query = query.Where(m => m.MaterialName == name);
            }
            totalCount = query.Count();

            // 对结果进行排序和分页
            var resultList = query.OrderBy(m => m.CreateDate)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToList();

            return resultList;
        }

        public List<GetChukuDanDTO> GetAllTShippingOrderDetailPlus(DateTime? startTime, DateTime? endTime, int? billType, int? houseid, string? name, int pageIndex, int pageSize, out int totalCount)
        {
            var listNoPage = Context.TShippingOrderDetails.AsEnumerable();
            if (billType != null)
                listNoPage = listNoPage.Where(s=>s.BillType==billType);
            if(houseid!=null)
                listNoPage=listNoPage.Where(s=>s.WarehouseId==houseid);
            if (name != null)
                listNoPage = listNoPage.Where(s => s.MaterialName.Contains(name));
            if(startTime!=null && endTime!=null)
                listNoPage = listNoPage.Where(s => s.CreateDate.GetValueOrDefault().Date >= startTime && s.CreateDate.GetValueOrDefault().Date<=endTime);
            var items = listNoPage.OrderByDescending(s => s.CreateDate).GroupBy(s => s.OrderSn);
            var list= items.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            totalCount = items.Count();
            List<GetChukuDanDTO> resList = new List<GetChukuDanDTO>();
            foreach (var item in list)
            {
                var key = item.Key;
                var lockCellList = new List<TShippingLockCellGetDTO>();
                var shippoutList = new List<TShippingOrderDetail>();
                foreach (var value in item)
                {
                    var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == value.Id);
                    foreach (var item1 in lockCell)
                    {
                        var lockCellDTO = new TShippingLockCellGetDTO();
                        lockCellDTO = mapper.Map<TShippingLockCellGetDTO>(item1);
                        lockCellDTO.InvCount = GetInvCount(item1.MaterialCode);
                        lockCellDTO.ProductionTime = ExtractDateFromCode(lockCellDTO.SmallBatchNo);
                        lockCellDTO.keChuCount= lockCellRepository.GetKeChuInvCount(lockCellDTO.MaterialCode);
                        lockCellList.Add(lockCellDTO);
                    }
                    shippoutList.Add(value);
                }
                resList.Add(new GetChukuDanDTO()
                {
                    Status = GetStatus(lockCellList),
                    OrderSn = key,
                    CreateTime = shippoutList[0].CreateDate,
                    Sum = shippoutList.Sum(s=>s.Qty),
                    CreateUserName= shippoutList[0].CreateUserName,
                    AuditUserName= shippoutList[0].AuditUserName,
                    shippingOrders = lockCellList,
                    Customer = shippoutList[0].CustomerName,
                    CarCode = shippoutList[0].CarCord
                });
            }
            return resList;
        }
        /// <summary>
        /// 给导出提供数据
        /// </summary>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="billType"></param>
        /// <param name="houseid"></param>
        /// <param name="name"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        public List<TShippingLockCellGetDTO> GetOuHouseToExcel(DateTime? startTime, DateTime? endTime, int? billType, int? houseid, string? name, int pageIndex, int pageSize, out int totalCount)
        {
            var listNoPage = Context.TShippingOrderDetails.AsEnumerable();
            if (billType != null)
                listNoPage = listNoPage.Where(s => s.BillType == billType);
            if (houseid != null)
                listNoPage = listNoPage.Where(s => s.WarehouseId == houseid);
            if (name != null)
                listNoPage = listNoPage.Where(s => s.MaterialName == name);
            if (startTime != null && endTime != null)
                listNoPage = listNoPage.Where(s => s.CreateDate.GetValueOrDefault().Date >= startTime && s.CreateDate.GetValueOrDefault().Date <= endTime);
            var items = listNoPage.OrderByDescending(s => s.CreateDate).GroupBy(s => s.OrderSn);
            var list = items.Skip((pageIndex - 1) * pageSize).Take(pageSize);
            totalCount = items.Count();
            List<TShippingLockCellGetDTO> resList = new List<TShippingLockCellGetDTO>();
            foreach (var item in list)
            {
                var key = item.Key;
                var lockCellList = new List<TShippingLockCellGetDTO>();
                var shippoutList = new List<TShippingOrderDetail>();
                foreach (var value in item)
                {
                    var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == value.Id);
                    foreach (var item1 in lockCell)
                    {
                        var lockCellDTO = new TShippingLockCellGetDTO();
                        lockCellDTO = mapper.Map<TShippingLockCellGetDTO>(item1);
                        lockCellDTO.OrdeSn = key;
                        lockCellDTO.InvCount = GetInvCount(item1.MaterialCode);
                        lockCellDTO.ProductionTime = ExtractDateFromCode(lockCellDTO.SmallBatchNo);
                        lockCellDTO.keChuCount = lockCellRepository.GetKeChuInvCount(lockCellDTO.MaterialCode);
                        lockCellDTO.CarCode = value.CarCord;
                        lockCellDTO.CustomerName = value.CustomerName;
                        lockCellList.Add(lockCellDTO);
                    }
                    shippoutList.Add(value);
                }
                resList.AddRange(lockCellList);
            }
            return resList;
        }
        private string GetStatus(List<TShippingLockCellGetDTO> shippingGoods)
        {
            if (shippingGoods.All(s => s.IsPicking==true))
            {
                return "已完成";
            }
            else if(shippingGoods.All(s => s.IsPicking == false))
            {
                return "创建";
            }
            else
            {
                return "出库中";
            }
        }
        private string GetStatus(List<TShippingLockCell> shippingGoods)
        {
            if (shippingGoods.All(s => s.IsPicking == true))
            {
                return "已完成";
            }
            else if (shippingGoods.All(s => s.IsPicking == false))
            {
                return "创建";
            }
            else
            {
                return "出库中";
            }
        }

        /// <summary>
        /// 根据单号查询明细
        /// </summary>
        /// <param name="orderSn"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TShippingOrderDetail> GetTShippingOrderDetailByOrderSn(string orderSn)
        {
            var list = Context.TShippingOrderDetails
                .Where(x => x.OrderSn == orderSn).ToList();

            return list;
        }

        public UpdGetOutOrder GetOneTShippingOrderDetailPlus(string orderSn)
        {
            var listNoPage = Context.TShippingOrderDetails.AsEnumerable().Where(s=>s.OrderSn==orderSn).ToList();
            if (listNoPage.Count() <= 0)
            {
                return null;
            }
            var items = listNoPage.OrderByDescending(s => s.CreateDate).GroupBy(s => s.OrderSn);
            UpdGetOutOrder resList=new UpdGetOutOrder();
            List<TShippingOrderDetailPlusLockCellDTO> lockCellDTOs = new List<TShippingOrderDetailPlusLockCellDTO>();
            foreach (var item in items)
            {
                var key = item.Key;
                var lockCellList = new List<TShippingLockCell>();
                var shippoutList = new List<TShippingOrderDetail>();
                foreach (var value in item)
                {
                    var lockCell = Context.TShippingLockCells.Where(s => s.OrderDetailId == value.Id);
                    foreach (var item1 in lockCell)
                    {
                        lockCellList.Add(item1);
                    }
                    shippoutList.Add(value);
                }

                foreach (var lockCell1 in lockCellList)
                {
                    var lockCellobj = new TShippingOrderDetailPlusLockCellDTO
                    (
                        lockCell1.Id,
                        lockCell1.MaterialId.GetValueOrDefault(),
                        lockCell1.MaterialName,
                        lockCell1.MaterialCode,
                        (int)lockCell1.OutQty.GetValueOrDefault()
                    );
                    lockCellDTOs.Add(lockCellobj);
                }
            }
            resList.OrderSn = listNoPage[0].OrderSn;
            resList.BillType = listNoPage[0].BillType.GetValueOrDefault();
            resList.CustomerId = listNoPage[0].CustomerId.GetValueOrDefault();
            resList.CarCode = listNoPage[0].CarCord;
            foreach (var item in lockCellDTOs.GroupBy(s => s.MaterialCode))
            {
                var lockCellobj = new TShippingOrderDetailPlusLockCellDTO
                (
                    item.First().TShippingLockCellsId,
                    item.First().MaterialId,
                    item.First().MaterialName,
                    item.First().MaterialCode,
                    item.Sum(s=>s.MaterialNum),
                    lockCellRepository.GetKeChuInvCount(item.First().MaterialCode)
                );
                resList.shippingOrderDetailPlusLockCellDTOs.Add(lockCellobj);
            }
            return resList;
        }
        private decimal? GetInvCount(string materialCode)
        {
            return Context.TInventories.Where(s => s.MaterialCode == materialCode).ToList().Sum(s => s.AvailableQty);
        }
        /// <summary>
        /// 小批次号拆解
        /// </summary>
        /// <param name="bacNo">小批次号</param>
        /// <returns></returns>
        private int ExtractDateFromCode(string bacNo)
        {
            if (string.IsNullOrEmpty(bacNo))
            {
                return 0;
            }
            if (bacNo.Length < 12)
            {
                return 0;
            }
            string time = bacNo.Substring(2, 8);
            bool containsLetter = time.Any(char.IsLetter);
            if (containsLetter)
            {
                return 0;
            }
            return Convert.ToInt32(time);
        }

        /// <summary>
        /// 采购退料
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddPurchaseRetreat(PurchaseRetreatDto model, out string msg)
        {
            msg = "添加采购退料单成功";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    //判断采购退料单是否重复
                    var orderSnIsHove = Context.TShippingOrderDetails.Where(s => s.OrderSn == model.OrderSn);
                    if (orderSnIsHove != null && orderSnIsHove.Count() > 0)
                    {
                        msg = "采购退料单号已存在";
                        return false;
                    }

                    //查询物料是否存在
                    foreach (var item in model.PurchaseRetreatDetailDtos)
                    {
                        var material = Context.TMaterials.FirstOrDefault(m => m.Code == item.TMaterialCode);
                        if (material == null)
                        {
                            msg = $"找不到此物料,物料：{item.TMaterialName},单号：{item.TMaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                        var inventory = Context.TInventories.FirstOrDefault(i => i.MaterialCode == item.TMaterialCode);
                        if (inventory == null)
                        {
                            msg = $"找不到此物料的库存信息,物料：{item.TMaterialName},单号：{item.TMaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                        if (inventory.AvailableQty < item.RetreatNum)
                        {
                            msg = $"物料库存不足,物料：{inventory.MaterialName},单号：{inventory.MaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                    }

                    TShippingOrderDetail shippingOrderDetail = new TShippingOrderDetail();
                    shippingOrderDetail.OrderSn = model.OrderSn;
                    shippingOrderDetail.PurchaseOrderSn = model.PurchaseOrderSn;
                    shippingOrderDetail.CompanyCode = model.CompanyCode;
                    shippingOrderDetail.CompanyName = model.CompanyName;
                    Context.TShippingOrderDetails.Add(shippingOrderDetail);
                    List<TShippingGoodsDetail> shippingGoodsDetails = new List<TShippingGoodsDetail>();
                    foreach (var item in model.PurchaseRetreatDetailDtos)
                    {
                        TShippingGoodsDetail shippingGoodsDetail = new TShippingGoodsDetail();
                        var material = Context.TMaterials.FirstOrDefault(m => m.Code == item.TMaterialCode);
                        shippingGoodsDetail.Iineitem = item.Iineitem;
                        shippingGoodsDetail.PurchaseIineitem = item.PurchaseIineitem;
                        //shippingGoodsDetail.OrderDetailId = shippingOrderDetail.Id;
                        shippingGoodsDetail.MaterialId = material.Id;
                        shippingGoodsDetail.MaterialCode = material.Code;
                        shippingGoodsDetail.MaterialName = material.Name;
                        shippingGoodsDetail.ModelSpec = item.ModelSpec;
                        shippingGoodsDetail.RetreatNum = item.RetreatNum;
                        shippingGoodsDetail.RetreatUnitName = item.RetreatUnitName;
                        shippingGoodsDetail.RetreatUnitCode = item.RetreatUnitCode;
                        shippingGoodsDetails.Add(shippingGoodsDetail);
                    }
                    Context.TShippingGoodsDetails.AddRange(shippingGoodsDetails);
                    if (Context.SaveChanges() <= 0)
                    {
                        msg = "添加采购退料单失败";
                        tran.Rollback();
                        return false;
                    }
                    //无异常提交事务
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //事务回滚
                    msg = "catch:" + ex.Message;
                    tran.Rollback();
                    return false;
                }
            }
        }

        /// <summary>
        /// 生产领料
        /// </summary>
        /// <param name="model"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool AddProductionRequisition(ProductionRequisitionDto model, out string msg)
        {
            msg = "添加生产领料单成功";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    //判断采购退料单是否重复
                    var orderSnIsHove = Context.TShippingOrderDetails.Where(s => s.OrderSn == model.OrderSn);
                    if (orderSnIsHove != null && orderSnIsHove.Count() > 0)
                    {
                        msg = "生产领料单号已存在";
                        return false;
                    }

                    //查询物料是否存在
                    foreach (var item in model.ProductionRequisitionDetailDtos)
                    {
                        var material = Context.TMaterials.FirstOrDefault(m => m.Code == item.MaterialCode);
                        if (material == null)
                        {
                            msg = $"找不到此物料,物料：{item.MaterialName},单号：{item.MaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                        var inventory = Context.TInventories.FirstOrDefault(i => i.MaterialCode == item.MaterialCode);
                        if (inventory == null)
                        {
                            msg = $"找不到此物料的库存信息,物料：{item.MaterialName},单号：{item.MaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                        if (inventory.AvailableQty < item.NeedNum)
                        {
                            msg = $"物料库存不足,物料：{inventory.MaterialName},单号：{inventory.MaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                    }

                    TShippingOrderDetail shippingOrderDetail = new TShippingOrderDetail();
                    shippingOrderDetail.OrderSn = model.OrderSn;
                    shippingOrderDetail.ProductionOrderSn = model.ProductionOrderSn;
                    shippingOrderDetail.CompanyCode = model.CompanyCode;
                    shippingOrderDetail.CompanyName = model.CompanyName;
                    shippingOrderDetail.ProductName = model.ProductName;
                    shippingOrderDetail.ProductCode = model.ProductCode;
                    shippingOrderDetail.ModelSpec = model.ModelSpec;
                    Context.TShippingOrderDetails.Add(shippingOrderDetail);
                    List<TShippingGoodsDetail> shippingGoodsDetails = new List<TShippingGoodsDetail>();
                    foreach (var item in model.ProductionRequisitionDetailDtos)
                    {
                        TShippingGoodsDetail shippingGoodsDetail = new TShippingGoodsDetail();
                        var material = Context.TMaterials.FirstOrDefault(m => m.Code == item.MaterialCode);
                        shippingGoodsDetail.Iineitem = item.Iineitem;
                        //shippingGoodsDetail.PurchaseIineitem = item.PurchaseIineitem;
                        //shippingGoodsDetail.OrderDetailId = shippingOrderDetail.Id;
                        shippingGoodsDetail.MaterialId = material.Id;
                        shippingGoodsDetail.MaterialCode = material.Code;
                        shippingGoodsDetail.MaterialName = material.Name;
                        shippingGoodsDetail.ModelSpec = item.ModelSpec;
                        shippingGoodsDetail.NeedNum = item.NeedNum;
                        shippingGoodsDetail.UnitName = item.UnitName;
                        shippingGoodsDetail.UnitCode = item.UnitCode;
                        shippingGoodsDetails.Add(shippingGoodsDetail);
                    }
                    Context.TShippingGoodsDetails.AddRange(shippingGoodsDetails);
                    if (Context.SaveChanges() <= 0)
                    {
                        msg = "添加生产领料单失败";
                        tran.Rollback();
                        return false;
                    }
                    //无异常提交事务
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //事务回滚
                    msg = "catch:" + ex.Message;
                    tran.Rollback();
                    return false;
                }
            }
        }

        /// <summary>
        /// 销售发货
        /// </summary>
        /// <param name="marketShipmentsDto"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool AddMarketShipments(MarketShipmentsDto model, out string msg)
        {
            msg = "添加销售发货单成功";
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    //判断采购退料单是否重复
                    var orderSnIsHove = Context.TShippingOrderDetails.Where(s => s.OrderSn == model.OrderSn);
                    if (orderSnIsHove != null && orderSnIsHove.Count() > 0)
                    {
                        msg = "销售发货单号已存在";
                        return false;
                    }

                    //查询物料是否存在
                    foreach (var item in model.MarketShipmentsDetailDtos)
                    {
                        var material = Context.TMaterials.FirstOrDefault(m => m.Code == item.MaterialCode);
                        if (material == null)
                        {
                            msg = $"找不到此物料,物料：{item.MaterialName},单号：{item.MaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                        var inventory = Context.TInventories.FirstOrDefault(i => i.MaterialCode == item.MaterialCode);
                        if (inventory == null)
                        {
                            msg = $"找不到此物料的库存信息,物料：{item.MaterialName},单号：{item.MaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                        if (inventory.AvailableQty < item.ShipmentsNum)
                        {
                            msg = $"物料库存不足,物料：{inventory.MaterialName},单号：{inventory.MaterialCode}";
                            tran.Rollback();
                            return false;
                        }
                        if(item.DeliveryTime <= DateTime.Now)
                        {
                            msg = $"收货日期不能小于发货日期";
                            tran.Rollback();
                            return false;
                        }
                    }

                    TShippingOrderDetail shippingOrderDetail = new TShippingOrderDetail();
                    shippingOrderDetail.OrderSn = model.OrderSn;
                    shippingOrderDetail.CompanyCode = model.CompanyCode;
                    shippingOrderDetail.CompanyName = model.CompanyName;
                    shippingOrderDetail.MarketOrderSn = model.MarketOrderSn;
                    shippingOrderDetail.ShipmentsTime = DateTime.Now;
                    shippingOrderDetail.ClientCode = model.ClientCode;
                    shippingOrderDetail.ClientName = model.ClientName;
                    Context.TShippingOrderDetails.Add(shippingOrderDetail);
                    List<TShippingGoodsDetail> shippingGoodsDetails = new List<TShippingGoodsDetail>();
                    foreach (var item in model.MarketShipmentsDetailDtos)
                    {
                        TShippingGoodsDetail shippingGoodsDetail = new TShippingGoodsDetail();
                        var material = Context.TMaterials.FirstOrDefault(m => m.Code == item.MaterialCode);
                        shippingGoodsDetail.Iineitem = item.Iineitem;
                        shippingGoodsDetail.MarketOrderSn = item.MarketOrderSn;
                        shippingGoodsDetail.MarketIineitem = item.MarketIineitem;
                        shippingGoodsDetail.MaterialId = material.Id;
                        shippingGoodsDetail.MaterialCode = material.Code;
                        shippingGoodsDetail.MaterialName = material.Name;
                        shippingGoodsDetail.ModelSpec = item.ModelSpec;
                        shippingGoodsDetail.ShipmentsNum = item.ShipmentsNum;
                        shippingGoodsDetail.UnitName = item.UnitName;
                        shippingGoodsDetail.UnitCode = item.UnitCode;
                        shippingGoodsDetail.DeliveryTime = item.DeliveryTime;
                        shippingGoodsDetails.Add(shippingGoodsDetail);
                    }
                    Context.TShippingGoodsDetails.AddRange(shippingGoodsDetails);
                    if (Context.SaveChanges() <= 0)
                    {
                        msg = "添加销售发货单失败";
                        tran.Rollback();
                        return false;
                    }
                    //无异常提交事务
                    tran.Commit();
                    return true;
                }
                catch (Exception ex)
                {
                    //事务回滚
                    msg = "catch:" + ex.Message;
                    tran.Rollback();
                    return false;
                }
            }
        }
    }
} 